#include <string.h>
#include <stdlib.h>
#include "eeprom_read_data.h"


#define  CK_IIC_SLAVE_ADDR_EEPROM_A0    0x50
#define  CK_IIC_SLAVE_ADDR_EEPROM_A2    0x51
#define  BLOCK_A0_IMAGE_DATA_START_ADDR 0x0105
#define  BLOCK_A0_IMAGE_DATA_END_ADDR   0xfffe //0xffff
#define  BLOCK_A0_PARAM_DATA_START_ADDR 0x0013
#define  BLOCK_A0_PARAM_DATA_END_ADDR   0x00ff
#define  BLOCK_A2_IMAGE_DATA_START_ADDR 0x0005


#define  BLOCK_A0_SN_DATA_START_ADDR   0x0000
#define  BLOCK_A0_SN_DATA_END_ADDR     0x0004


static i2c_dev_t i2c_eeprom;

uint32_t HexToNum(uint8_t *data,int size){
    uint32_t num = 0;
	for(int i = 0; i<size; i++){
		num=num*10+(data[i]-0x30);
	}
	return num;
}

int eeprom_init(i2c_dev_t *i2c, uint32_t dev_addr){
    int ret = 0;
    i2c->port = IIC_PORT_USI_11;
	i2c->config.dev_addr = dev_addr;
    i2c->universal = 1;	//for fullmask
	i2c->i2cNo = 1;
	i2c->config.freq = I2C_BUS_BIT_RATES_400K;
	ret = hal_i2c_init(i2c);
    return ret;
}

int eeprom_read_data(i2c_dev_t *i2c,uint16_t begain_addr,uint16_t end_addr,uint8_t *data_image)
{
    uint8_t data = 0;
	uint16_t flag = begain_addr;
    int ret = 0;
	for(;begain_addr<end_addr;begain_addr++){
		ret = iic_read16bit(i2c, begain_addr, &data);
		if(ret<0)
    	{
       		printf("eeprom read data failed!\n");
        	return -1;
    	} 
		data_image[begain_addr-flag] = data;
		data = 0;
		//printf(" 0x%x \r",data_image[begain_addr-flag]);
	}

	if((begain_addr >= BLOCK_A0_IMAGE_DATA_END_ADDR) && (begain_addr == end_addr)){
		ret = iic_read16bit(i2c, begain_addr, &data);
		data_image[begain_addr-flag] = data;
	}

    return 0;
}

int eeprom_read_intri_param(double *intri_param){
	uint8_t num_space = 0,count = 0 ,flag = 0;
	char *value = NULL;
	uint8_t intri_data[237]={0};
	//uint16_t intri_addr = 0x0013;
	eeprom_init(&i2c_eeprom,CK_IIC_SLAVE_ADDR_EEPROM_A0);
	eeprom_read_data(&i2c_eeprom,BLOCK_A0_PARAM_DATA_START_ADDR,BLOCK_A0_PARAM_DATA_END_ADDR,intri_data);
	for(int i = 0; i<237; i++){
		if((intri_data[i]!=0x20)||(intri_data[i]!=0x0a))
			*(value+i-num_space) = intri_data[i];
		if((intri_data[i]==0x20)||(intri_data[i]==0x0a)){
			if((intri_data[i-1]==0x20)||(intri_data[i-1]==0x0a))
				continue;
			if(flag == 8){
				flag++;
				continue;
			}
			intri_param[count] = atof(value);
			//printf("intri param is %.15f\n",intri_param[count]);
			count++;
			flag++;
			num_space = i;
			value = (char *)&intri_data[i];			
		}
	}
	return 0;
}

int eeprom_read_image_data(uint8_t * image_data){
    uint32_t data_size = 0,block_A0_size = 0,block_A2_size = 0;
	uint8_t val_A0[5] = {0};
	uint8_t val_A2[5] = {0};
	eeprom_init(&i2c_eeprom,CK_IIC_SLAVE_ADDR_EEPROM_A0);
	eeprom_read_data(&i2c_eeprom,0x0100,0x0105,val_A0);
	block_A0_size = HexToNum(val_A0,sizeof(val_A0)/sizeof(val_A0[0]));
	printf("0x%02x 0x%02x 0x%02x 0x%02x 0x%02x \n", val_A0[0], val_A0[1], val_A0[2], val_A0[3], val_A0[4]);
	printf("block_A0_size is %d\n",block_A0_size);

	data_size += block_A0_size;
	//eeprom_read_data(&i2c_eeprom,BLOCK_A0_IMAGE_DATA_START_ADDR,BLOCK_A0_IMAGE_DATA_END_ADDR,image_data);
	eeprom_read_data(&i2c_eeprom,BLOCK_A0_IMAGE_DATA_START_ADDR,BLOCK_A0_IMAGE_DATA_START_ADDR+(block_A0_size-1),image_data);

	eeprom_init(&i2c_eeprom,CK_IIC_SLAVE_ADDR_EEPROM_A2);
	eeprom_read_data(&i2c_eeprom,0x0000,BLOCK_A2_IMAGE_DATA_START_ADDR,val_A2);
	block_A2_size = HexToNum(val_A2,sizeof(val_A2)/sizeof(val_A2[0]));
	printf("block_A2_size is %d\n",block_A2_size);
	data_size += block_A2_size;

	eeprom_read_data(&i2c_eeprom,BLOCK_A2_IMAGE_DATA_START_ADDR,BLOCK_A2_IMAGE_DATA_START_ADDR+block_A2_size,image_data+block_A0_size);
		
	return data_size;
}


uint32_t eeprom_read_SN_data(void)
{
	int ret = 0;
	uint32_t SN;
	SN_inf_t dev_sn_inf;
	char sensor_type_name[3][8] = {"SL","Tof","Stereo"};
	uint8_t number_dev[4]={0};

	static i2c_dev_t i2c_eeprom_user;

	ret = eeprom_init(&i2c_eeprom_user,CK_IIC_SLAVE_ADDR_EEPROM_A0);
	if(ret < 0)
		return 0;

	ret = eeprom_read_data(&i2c_eeprom_user,BLOCK_A0_SN_DATA_START_ADDR,BLOCK_A0_SN_DATA_END_ADDR,number_dev);
	if(ret < 0)
		return 0;
	
	printf("number %02x %02x %02x %02x\n", number_dev[0],number_dev[1],number_dev[2],number_dev[3]);
	
	SN = (((number_dev[0]&0x07)<<29)&0xE0000000)|(((number_dev[0]&0xF8)<<21)&0x1F000000)\
		 |(((number_dev[1]&0x0f)<<20)&0x00F00000)|(((number_dev[1]&0xF0)<<10)&0x0003C000)\
		 |(((number_dev[2]&0x03)<<18)&0x000C0000)|(((number_dev[2]&0xFC)>>2)&0x0000003F)\
		 |((number_dev[3]<<6)&0x00003FC0);
	
	dev_sn_inf.name_type = (SN>>29)&0x0F;
	dev_sn_inf.part_number = (SN>>24)&0x1F;
	dev_sn_inf.year_number = ((SN>>20)&0x0F)+20;
	dev_sn_inf.week_number = (SN>>14)&0x3F;
	dev_sn_inf.product_ID = (uint16_t)(SN&0x00003FFF);
	printf("SN = %08x\n",SN);
	printf("serial number: %s%02d-%d%d-%d \n",sensor_type_name[dev_sn_inf.name_type-1],dev_sn_inf.part_number,\
	 						dev_sn_inf.year_number,dev_sn_inf.week_number,dev_sn_inf.product_ID);

	return SN;
}

